Back to videos

Grid Placement is Easy - Walls and Ceilings? Here's What It Took (Three.js)

Overview

As we continue building Pascal, our browser-based 3D home editor inspired by The Sims, we’ve started adding real, placeable items to the scene — furniture, appliances, TVs, and lamps.

Snapping items to a floor grid is straightforward.

But as soon as you want to mount a TV on a wall, hang a lamp from the ceiling, or attach objects to surfaces, grid-based placement breaks down.

In this episode, I walk through the event-driven system we built to make grid, wall, and ceiling placement work together in a clean and scalable way.

From Grid Snapping to Surface Placement

Placing an item on the grid is simple: move, snap, click.

The real challenge starts when items need to attach to walls or ceilings.

Pascal is built around a scene graph that represents the building structure — levels contain walls, walls contain items, and items can have nested children. This allows us to render everything from data and move parent nodes while all descendants update automatically.

To modify this scene graph, we use small tools that react to events to add, update, or delete nodes. Rendering is fully decoupled and updates automatically.

Grid placement is handled by a grid-tiles component that emits custom events like grid:move and grid:click. Tools listen to these events and update the active item. When the user confirms, the placement is committed.

Walls and ceilings follow the same pattern.

Wall and ceiling renderers emit their own events (wall:enter, wall:move, etc.). For wall placement, we pass the surface normal, allowing items to automatically rotate and always face the correct direction. Ceiling items snap the same way and become children of the ceiling node.

To control where items are allowed to attach, each catalog item defines its supported surfaces:

  • Floor

  • Wall

  • Wall-side

  • Ceiling

This keeps the placement logic generic while allowing different behaviors for TVs, paintings, doors, or windows.

The result is a single, event-driven system that handles grid, wall, and ceiling placement cleanly, without special-case logic.

Resources/Tech Stack

#threejs #js #devlog

Need help with this tutorial? Join our Discord community!